package com.zlh;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.transaction.CuratorOp;
import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.CreateMode;

import java.util.List;

/**
 * @package PACKAGE_NAME
 * @company: dacheng
 * @author: zlh
 * @createDate: 2021/4/26
 */
public class ZkCuratorDemo {
    /** Apache Curator实例，以便与ZooKeeper连接 */
    private CuratorFramework curator;
    private final String zkConnect = "192.168.50.100:12181";

    {
        curator = CuratorFrameworkFactory.newClient(zkConnect, new RetryNTimes(10, 30000));
        curator.start();
    }

    /**
     * 查询
     */
    public void query() throws Exception {
        final String topicName = "dc_test_ck_es";
        // 获取目录下所有一级子节点(ids、topics、seqid)，相当于ls命令
        List<String> dirs = curator.getChildren().forPath("/brokers");
        for (String dir:dirs){
            System.out.println("获取目录下所有子节点路径："+dir);
        }
        // 查看topic有几个分区
        List<String> partitions = curator.getChildren().forPath("/brokers/topics/" + topicName + "/partitions");
        System.out.println("topic: "+topicName+"的分区数有"+partitions.size()+"个。");
        // 相当于get命令
        byte[] bytes = curator.getData().forPath("/brokers/ids/0");
        String ids = new String(bytes);
        System.out.println(ids);
        // 创建路径,指定创建模式（临时节点),自动创建父目录且初始化内容
        curator.create().creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .forPath("/curator/testDir","foo1".getBytes());
        // 更新节点内容
        curator.setData().forPath("/curator/testDir","{\"value\":\"更新节点内容\"}".getBytes());
        byte[] testDir = curator.getData().forPath("/curator/testDir");
        System.out.println(new String(testDir));
        // 强制保证递归删除所有节点
        curator.delete().guaranteed().deletingChildrenIfNeeded().forPath("/curator");
    }

    /**
     * zk事物
     * @throws Exception
     */
    public void zkTransaction() throws Exception {
        // 构建三组事物操作
        CuratorOp createOp = curator.transactionOp().create()
                .forPath("/curator/one_path","some data".getBytes());
        CuratorOp setDataOp = curator.transactionOp().setData()
                .forPath("/curator","other data".getBytes());
        //因为节点“/curator”存在子节点，所以在删除的时候将会报错，事务回滚
        CuratorOp deleteOp = curator.transactionOp().delete()
                .forPath("/curator");
        // 加入事物组，事务执行结果
        List<CuratorTransactionResult> results = curator.transaction()
                .forOperations(createOp,setDataOp,deleteOp);
        //遍历输出结果
        for(CuratorTransactionResult result : results){
            System.out.println("执行结果是： " + result.getForPath() + "--" + result.getType());
        }
    }

    public static void main(String[] args) throws Exception {
        ZkCuratorDemo zkCurator = new ZkCuratorDemo();
        zkCurator.query();
        zkCurator.zkTransaction();
    }
}
